package com.spark.lola.job;

import com.spark.lola.entity.gds.ProductInfo;
import com.spark.lola.entity.sup.SupplierInfo;
import com.spark.lola.feign.GdsFeignService;
import com.spark.lola.feign.LogisticsFeignService;
import com.spark.lola.feign.SupFeignService;
import com.spark.lola.logistics.entity.LocationInfo;
import com.spark.lola.mapper.statistics.StatisticsCarMapper;
import com.spark.lola.mapper.statistics.StatisticsDriverMapper;
import com.spark.lola.mapper.statistics.StatisticsLogisticsMapper;
import com.spark.lola.service.statistics.*;
import com.spark.lola.statistics.entity.*;
import com.spark.lola.support.common.entity.ShiroUser;
import com.spark.lola.support.common.util.TimeUtil;
import com.spark.lola.support.wms.cache.CollectionCache;
import com.spark.lola.support.wms.configuration.WmsProperties;
import com.spark.lola.support.wms.constant.KafkaTopic;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.print.attribute.standard.Destination;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Author: DengYeJun
 * @Date: 2020/5/12 11:27
 */
@Component
public class StatisticsJob {
    private Logger logger = LoggerFactory.getLogger(StatisticsJob.class);
    private GdsFeignService gdsFeignService;
    private SupFeignService supFeignService;
    private IStatisticsProductService productService;
    private IStatisticsSupplierService supplierService;
    private IStatisticsSalesmanService salesmanService;
    private StatisticsLogisticsService statisticsLogisticsService;
    private StatisticsDriverService statisticsDriverService;
    private StatisticsCarService statisticsCarService;
    private StatisticsLogisticsMapper statisticsLogisticsMapper;
    private StatisticsDriverMapper statisticsDriverMapper;
    private StatisticsCarMapper statisticsCarMapper;
    private IStatisticsDestinationService destinationService;
    private WmsProperties wmsProperties;
    private LogisticsFeignService logisticsFeignService;
    private KafkaTemplate kafkaTemplate;

    @Autowired
    public StatisticsJob(GdsFeignService gdsFeignService,
                         SupFeignService supFeignService,
                         IStatisticsProductService productService,
                         IStatisticsSupplierService supplierService,
                         StatisticsLogisticsService statisticsLogisticsService,
                         StatisticsDriverService statisticsDriverService,
                         StatisticsCarService statisticsCarService,
                         StatisticsLogisticsMapper statisticsLogisticsMapper,
                         StatisticsDriverMapper statisticsDriverMapper,
                         StatisticsCarMapper statisticsCarMapper,
                         IStatisticsDestinationService destinationService,
                         IStatisticsSalesmanService salesmanService,
                         WmsProperties wmsProperties,
                         LogisticsFeignService logisticsFeignService,
                         KafkaTemplate kafkaTemplate) {
        this.gdsFeignService = gdsFeignService;
        this.supFeignService = supFeignService;
        this.productService = productService;
        this.supplierService = supplierService;
        this.statisticsLogisticsService = statisticsLogisticsService;
        this.statisticsDriverService = statisticsDriverService;
        this.statisticsCarService = statisticsCarService;
        this.statisticsLogisticsMapper = statisticsLogisticsMapper;
        this.statisticsDriverMapper = statisticsDriverMapper;
        this.statisticsCarMapper = statisticsCarMapper;
        this.destinationService = destinationService;
        this.salesmanService = salesmanService;
        this.wmsProperties = wmsProperties;
        this.logisticsFeignService = logisticsFeignService;
        this.kafkaTemplate = kafkaTemplate;
    }

    /**
     * 创建每日货品统计记录
     */
    @Scheduled(cron = "0 10 0 * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void createProduct() {
        logger.info("===创建每日货品统计记录===START===");
        List<ProductInfo> lst = gdsFeignService.findProduct(0L, null);
        if (CollectionUtils.isEmpty(lst)) {
            logger.error("===无货品数据");
            return;
        }
        Date now = new Date();
        Date yesterdayDate = new Date(now.getTime() - 86400000L);
        List<StatisticsProduct> statistics = new ArrayList<>();

        lst.forEach(productInfo -> {
            StatisticsProduct model = new StatisticsProduct(productInfo.getId(), now);
            statistics.add(model);
        });
        logger.info("===待创建货品记录【{}】", statistics.size());
        if (!productService.saveBatch(statistics)) {
            logger.error("===创建失败");
        } else {
            statistics.forEach(o -> {
                kafkaTemplate.send(KafkaTopic.STATISTICS_CAL_PRODCUT, o.getParentId().toString(), TimeUtil.getTime(yesterdayDate));
            });
        }
        logger.info("===创建每日货品统计记录===END===");
    }

    /**
     * 创建每日纸厂统计记录
     */
    @Scheduled(cron = "0 15 0 * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void createDestination() {
        logger.info("===创建每日纸厂统计记录===START===");
        List<LocationInfo> lst = logisticsFeignService.getCompany();
        if (CollectionUtils.isEmpty(lst)) {
            logger.error("===无纸厂数据");
            return;
        }
        Date now = new Date();
        Date yesterdayDate = new Date(now.getTime() - 86400000L);
        List<StatisticsDestination> statistics = new ArrayList<>();

        lst.forEach(locationInfo -> {
            StatisticsDestination model = new StatisticsDestination(locationInfo.getId(), locationInfo.getName(), now);
            statistics.add(model);
        });
        logger.info("===待创建纸厂记录【{}】", statistics.size());
        if (!destinationService.saveBatch(statistics)) {
            logger.error("===创建失败");
        } else {
            statistics.forEach(o -> {
                kafkaTemplate.send(KafkaTopic.STATISTICS_CAL_DESTINATION, o.getParentId().toString(), TimeUtil.getTime(yesterdayDate));
            });
        }
        logger.info("===创建每日纸厂统计记录===END===");
    }

    /**
     * 创建供应商统计记录
     */
    @Scheduled(cron = "0 20 0 * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void createSupllier() {
        logger.info("===创建供应商统计记录===START===");
        List<SupplierInfo> suppliers = supFeignService.supliers();
        if (CollectionUtils.isEmpty(suppliers)) {
            logger.error("===无供应商数据");
            return;
        }
        Date now = new Date();
        Date yesterdayDate = new Date(now.getTime() - 86400000L);

        List<StatisticsSupplier> statistics = new ArrayList<>();
        suppliers.forEach(supplierInfo -> {
            StatisticsSupplier model = new StatisticsSupplier(supplierInfo.getId(), now);
            statistics.add(model);
        });
        logger.info("===待创建供应商记录【{}】", statistics.size());
        if (!supplierService.saveBatch(statistics)) {
            logger.error("===创建失败");
        } else {
            statistics.forEach(o -> {
                // 审计上日统计
                kafkaTemplate.send(KafkaTopic.STATISTICS_CAL_SUPPLIER, o.getParentId().toString(), TimeUtil.getTime(yesterdayDate));
            });
        }
        logger.info("===创建供应商统计记录===END===");
    }

    /**
     * 创建业务员统计记录
     */
    @Scheduled(cron = "0 25 0 * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void createSalesman() {
        logger.info("===创建业务员统计记录===START===");
        // 获取业务员列表
        List<ShiroUser> salesmans = CollectionCache.dutyEmployees.get(wmsProperties.getPurchase().getDutyId().get(1));
        if (CollectionUtils.isEmpty(salesmans)) {
            logger.error("===无业务员数据");
            return;
        }
        Date now = new Date();
        Date yesterdayDate = new Date(now.getTime() - 86400000L);
        List<StatisticsSalesman> statistics = new ArrayList<>();
        salesmans.forEach(salesman -> {
            StatisticsSalesman model = new StatisticsSalesman(salesman.getId(), now);
            statistics.add(model);
        });
        logger.info("===待创建业务员记录【{}】", statistics.size());
        if (!salesmanService.saveBatch(statistics)) {
            logger.error("===创建失败");
        } else {
            statistics.forEach(o -> {
                // 审计上日统计
                kafkaTemplate.send(KafkaTopic.STATISTICS_CAL_SALESMAN, o.getParentId().toString(), TimeUtil.getTime(yesterdayDate));
            });
        }
        logger.info("===创建业务员统计记录===END===");
    }

    /**
     * 创建每日货运统计记录
     */
    @Scheduled(cron = "0 30 0 * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void createLogistics() throws ParseException {
        // 开始时间
        Date startTime = getTime().get("startTime");
        // 结束时间
        Date endTime = getTime().get("endTime");
        // 查询本日已有-删除
        Long id = statisticsLogisticsMapper.findHaveByCreateDate(startTime);
        if (id != null) {
            statisticsLogisticsService.removeById(id);
        }
        StatisticsLogistics statisticsLogistics = logisticsFeignService.getStatisticsLogistics(startTime, endTime);
        if (statisticsLogistics == null) {
            logger.error("===无统计数据");
            return;
        }
        if (!statisticsLogisticsService.save(statisticsLogistics)) {
            logger.error("===创建失败");
        }
        logger.info("===创建每日货品统计记录===END===");
    }

    /**
     * 创建每日驾驶员货运统计记录
     */
    @Scheduled(cron = "0 35 0 * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void createLogisticsDriver() throws ParseException {
        // 开始时间
        Date startTime = getTime().get("startTime");
        // 结束时间
        Date endTime = getTime().get("endTime");
        // 查询本日已有-删除
        List<Long> ids = statisticsDriverMapper.findHaveByDriverIdAndCreateDate(startTime);
        if (!CollectionUtils.isEmpty(ids)) {
            statisticsDriverMapper.deleteByIds(StringUtils.join(ids.toArray(), ","));
        }
        List<StatisticsDriver> statisticsDriverList = logisticsFeignService.getStatisticsDriver(startTime, endTime);
        if (CollectionUtils.isEmpty(statisticsDriverList)) {
            logger.error("===无统计数据");
            return;
        }
        if (!statisticsDriverService.saveBatch(statisticsDriverList)) {
            logger.error("===创建失败");
        }
        logger.info("===创建每日货品统计记录===END===");
    }

    /**
     * 创建每日车辆货运统计记录
     */
    @Scheduled(cron = "0 40 0 * * ?")
    @Transactional(rollbackFor = Exception.class)
    public void createLogisticsCar() throws ParseException {
        // 开始时间
        Date startTime = getTime().get("startTime");
        // 结束时间
        Date endTime = getTime().get("endTime");
        // 查询本日已有-删除
        List<Long> ids = statisticsCarMapper.findHaveByCarIdAndCreateDate(startTime);
        if (!CollectionUtils.isEmpty(ids)) {
            statisticsCarMapper.deleteByIds(StringUtils.join(ids.toArray(), ","));
        }
        List<StatisticsCar> statisticsCarList = logisticsFeignService.getStatisticsCar(startTime, endTime);
        if (CollectionUtils.isEmpty(statisticsCarList)) {
            logger.error("===无统计数据");
            return;
        }
        if (!statisticsCarService.saveBatch(statisticsCarList)) {
            logger.error("===创建失败");
        }
        logger.info("===创建每日货品统计记录===END===");
    }

    private Map<String, Date> getTime() throws ParseException {
        // 计算时间
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        DateFormat dateFormat_start = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
        DateFormat dateFormat_end = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
        // 开始时间
        Date startTime = simpleDateFormat.parse(dateFormat_start.format(new Date()));
        // 结束时间
        Date endTime = simpleDateFormat.parse(dateFormat_end.format(new Date()));
        Map<String, Date> map = new HashMap<>();
        map.put("startTime",startTime);
        map.put("endTime",endTime);
        return map;
    }
}
